package me.magicall.web.simple.spring.util;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import me.magicall.coll.CollFactory;
import me.magicall.coll.ElementTransformer;
import me.magicall.convenient.ResultView;
import me.magicall.db.Condition;
import me.magicall.db.model.BaseModel.MapModel;
import me.magicall.db.outsea.AddSqlConfig;
import me.magicall.db.outsea.CountSqlConfig;
import me.magicall.db.outsea.GetOneSqlConfig;
import me.magicall.db.outsea.ListSqlConfig;
import me.magicall.db.outsea.UpdateSqlConfig;
import me.magicall.db.outsea.springjdbc.Add;
import me.magicall.db.outsea.springjdbc.Count;
import me.magicall.db.outsea.springjdbc.GetList;
import me.magicall.db.outsea.springjdbc.GetOne;
import me.magicall.db.outsea.springjdbc.Update;
import me.magicall.db.util.AboutNull;
import me.magicall.db.util.OptionOnExist;
import me.magicall.db.util.PageInfo;
import me.magicall.util.kit.Kits;

import org.springframework.ui.ModelMap;
import org.springframework.web.servlet.view.UrlBasedViewResolver;

public class U {

	public static List<? extends Comparable<?>> parseToRangeNumber(final String idStr, final int maxSize) {
		if (idStr.contains("~") || idStr.contains("-")) {//1~10
			final String[] idStrs = idStr.split("~|-");
			final String startIdStr = idStrs[0];
			final String endIdStr = idStrs[1];
			final long startId = Kits.LONG.fromString(startIdStr);
			final long endId = Kits.LONG.fromString(endIdStr);
			final int size = (int) (endId - startId) + 1;
			return CollFactory.L.seq(startId, Math.min(size, maxSize));
		}
		return Kits.LIST.emptyValue();
	}

	public static List<? extends Comparable<?>> parseNumbers(final String idStr, final int maxSize) {
		List<? extends Comparable<?>> ids;
		if (idStr.contains("~")) {//1~10
			ids = parseToRangeNumber(idStr, maxSize);
		} else {//1,2,3,4
			final String[] idStrs = idStr.split(",");
			ids = Kits.LIST.head(Kits.LIST.transform(Arrays.asList(idStrs), new ElementTransformer<String, Long>() {
				@Override
				public Long transform(final int index, final String element) {
					return Kits.LONG.fromString(element);
				}
			}), maxSize);

		}
		return ids;
	}

	public static String forward(final String other) {
		return UrlBasedViewResolver.FORWARD_URL_PREFIX + other;
	}

	public static String redirect(final String other) {
		return UrlBasedViewResolver.REDIRECT_URL_PREFIX + other;
	}

	public static void setModelName(final ModelMap modelMap, final String modelName) {
		modelMap.addAttribute("modelName", modelName);
	}

	public static void setOne(final ModelMap modelMap, final Object model) {
		modelMap.addAttribute("cur", model);
	}

	public static ResultView<MapModel<?>> resultView(final ListSqlConfig<MapModel<?>> sqlConfig, final GetList<MapModel<?>> getList,
			final Count<MapModel<?>> count) {
		final List<MapModel<?>> list = getList.exe(sqlConfig);
		if (Kits.COLL.isEmpty(list)) {
			return ResultView.emptyResultView();
		}
		final PageInfo pageInfo = sqlConfig.getPageInfo();
		final CountSqlConfig<MapModel<?>> countSqlConfig = count.createSqlConfig(sqlConfig.getMainModelName());
		countSqlConfig.addConditions(sqlConfig.getConditions());
		countSqlConfig.addOtherModelsNames(sqlConfig.getOtherModelsNames());
		return new ResultView<MapModel<?>>(list, count.exe(countSqlConfig), pageInfo.getOffset(), pageInfo.getSize());
	}

	public static MapModel<?> getById(final String modelName, final Object id, final GetOne<MapModel<?>> getOne) {
		final GetOneSqlConfig<MapModel<?>> sqlConfig = getOne.createSqlConfig(modelName);
		sqlConfig.addConditions(new Condition("id", id));
		return getOne.exe(sqlConfig);
	}

	public static List<MapModel<?>> getById(final String modelName, final Collection<? extends Object> ids, final GetList<MapModel<?>> getList) {
		final ListSqlConfig<MapModel<?>> sqlConfig = getList.createSqlConfig(modelName);
		sqlConfig.addConditions(new Condition("id", ids));
		return getList.exe(sqlConfig);
	}

	public static int addOrUpdate(final String modelName, final Add<MapModel<?>> add, final Collection<MapModel<?>> models) {
		final AddSqlConfig<MapModel<?>> sqlConfig = add.createSqlConfig(modelName);
		sqlConfig.setRefedModels(models);
		sqlConfig.setOptionOnExist(OptionOnExist.REPLACE);
		sqlConfig.setAboutNull(AboutNull.ESCAPE);
		return add.exe(sqlConfig);
	}

	public static int addReturnKey(final String modelName, final Add<MapModel<?>> add, final MapModel<?>... models) {
		final AddSqlConfig<MapModel<?>> sqlConfig = add.createSqlConfig(modelName);
		sqlConfig.setRefedModels(models);
		sqlConfig.setOptionOnExist(OptionOnExist.EXCEPTION);
		sqlConfig.setAboutNull(AboutNull.ESCAPE);
		return add.exe(sqlConfig);
	}

	public static int addReturnKey(final String modelName, final Add<MapModel<?>> add, final Collection<MapModel<?>> models) {
		final AddSqlConfig<MapModel<?>> sqlConfig = add.createSqlConfig(modelName);
		sqlConfig.setRefedModels(models);
		sqlConfig.setOptionOnExist(OptionOnExist.EXCEPTION);
		sqlConfig.setAboutNull(AboutNull.ESCAPE);
		return add.exe(sqlConfig);
	}

	public static int addOrUpdate(final String modelName, final Add<MapModel<?>> add, final MapModel<?>... models) {
		final AddSqlConfig<MapModel<?>> sqlConfig = add.createSqlConfig(modelName);
		sqlConfig.setRefedModels(models);
		sqlConfig.setOptionOnExist(OptionOnExist.REPLACE);
		sqlConfig.setAboutNull(AboutNull.ESCAPE);
		return add.exe(sqlConfig);
	}

	public static int update(final String modelName, final Update<MapModel<?>> update, final Object id, final MapModel<?> refedModel) {
		final UpdateSqlConfig<MapModel<?>> sqlConfig = update.createSqlConfig(modelName);
		sqlConfig.setAboutNull(AboutNull.ESCAPE);
		sqlConfig.setRefedModel(refedModel);
		sqlConfig.addConditions(new Condition("id", id));
		return update.exe(sqlConfig);
	}
}
